/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



package sonia.golf;

//~--- non-JDK imports --------------------------------------------------------

import android.app.AlertDialog;
import android.app.ListActivity;

import android.content.DialogInterface;

import android.os.Bundle;

import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;

import sonia.golf.dao.DAOListener;
import sonia.golf.dao.DAOListener.DAOEvent;
import sonia.golf.dao.GenericDAO;
import sonia.golf.view.DefaultNewItemDialog;
import sonia.golf.view.OnOkListener;
import sonia.golf.view.SingleAdapter;

//~--- JDK imports ------------------------------------------------------------

import java.util.List;

/**
 *
 * @author Sebastian Sdorra
 *
 * @param <T>
 * @param <K>
 */
public abstract class AbstractDAOListActivity<T, K> extends ListActivity
        implements DAOListener<T>
{

  /**
   * Method description
   *
   *
   * @param name
   *
   * @return
   */
  protected abstract T createNewItem(String name);

  //~--- get methods ----------------------------------------------------------

  /**
   * Method description
   *
   *
   * @return
   */
  protected abstract GenericDAO<T, K> getDAO();

  /**
   * Method description
   *
   *
   * @return
   */
  protected abstract int getMenuId();

  /**
   * Method description
   *
   *
   * @return
   */
  protected abstract int getNewItemMenuId();

  /**
   * Method description
   *
   *
   * @return
   */
  protected abstract int getNewItemMessageId();

  /**
   * Method description
   *
   *
   * @param item
   *
   * @return
   */
  protected abstract String getRemoveMessage(T item);

  //~--- methods --------------------------------------------------------------

  /**
   * Method description
   *
   *
   * @param menu
   *
   * @return
   */
  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {
    MenuInflater mi = getMenuInflater();

    mi.inflate(getMenuId(), menu);

    return true;
  }

  /**
   * Method description
   *
   *
   * @param item
   * @param event
   */
  public void onEvent(T item, DAOEvent event)
  {
    boolean update = true;

    switch (event)
    {
      case ADD :
        itemList.add(item);

        break;

      case REMOVE :
        itemList.remove(item);

        break;

      default :
        update = false;
    }

    if (update)
    {
      adapter.notifyDataSetChanged();
    }
  }

  /**
   * Method description
   *
   *
   * @param featureId
   * @param item
   *
   * @return
   */
  @Override
  public boolean onMenuItemSelected(int featureId, MenuItem item)
  {
    int id = item.getItemId();

    if (id == getNewItemMenuId())
    {
      createNewItemDialog();
    }
    else if (id == R.id.menu_quit)
    {
      System.exit(RESULT_OK);
    }

    return true;
  }

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void addItem(T item)
  {
    preAdd(item);
    dao.add(item);
    postAdd(item);
  }

  /**
   * Method description
   *
   */
  protected void createNewItemDialog()
  {
    DefaultNewItemDialog dialog = new DefaultNewItemDialog(this,
                                    getNewItemMessageId());

    dialog.setOnOkListener(new OnOkListener()
    {
      public void onOk(String name)
      {
        T item = createNewItem(name);

        addItem(item);
      }
    });
    dialog.show();
  }

  /**
   * Method description
   *
   *
   * @param savedInstanceState
   */
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    dao = getDAO();
    itemList = dao.getAll();
    dao.addListener(this);
    adapter = getAdapter();
    setListAdapter(adapter);
    getListView().setOnItemLongClickListener(new OnItemLongClickListener()
    {
      public boolean onItemLongClick(AdapterView<?> av, View view, int i,
                                     long l)
      {
        T item = adapter.getItem(i);

        showRemoveDialog(item);

        return true;
      }
    });
  }

  /**
   * Method description
   *
   */
  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    dao.removeListener(this);
  }

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void postAdd(T item) {}

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void postRemove(T item) {}

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void preAdd(T item) {}

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void preRemove(T item) {}

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void removeItem(T item)
  {
    preRemove(item);
    dao.remove(item);
    postRemove(item);
  }

  /**
   * Method description
   *
   *
   * @param item
   */
  protected void showRemoveDialog(final T item)
  {
    AlertDialog.Builder dialog = new AlertDialog.Builder(this);

    dialog.setMessage(getRemoveMessage(item));
    dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface di, int i)
      {
        removeItem(item);
      }
    });
    dialog.setNegativeButton(R.string.cancel,
                             new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface di, int i)
      {

        // nothing todo
      }
    });
    dialog.show();
  }

  //~--- get methods ----------------------------------------------------------

  /**
   * Method description
   *
   *
   * @return
   */
  protected ArrayAdapter<T> getAdapter()
  {
    return new SingleAdapter<T>(this, itemList);
  }

  //~--- fields ---------------------------------------------------------------

  /** Field description */
  protected ArrayAdapter<T> adapter;

  /** Field description */
  protected GenericDAO<T, K> dao;

  /** Field description */
  protected List<T> itemList;
}
